import json
import logging
import os
import pathlib

from .ContentSpider import ContentSpider
from .DownloadInfo import DownloadInfo
from .MetaSpider import MetaSpider, MetaList
from .common import meta_file_name


class AlbumInfo:
    """
    一个记录相册元数据和下载信息的类
    """

    def __init__(self,
                 meta_list: MetaList,
                 content_download_info: DownloadInfo):
        """
        初始化AlbumDownloadInfo
        :param meta_list: 元数据列表，包含元数据下载信息
        :param content_download_info: 如何下载内容
        """
        self.meta_list = meta_list
        self.content_download_info = content_download_info

    def serialize(self) -> dict:
        return {'meta_list': self.meta_list.serialize(),
                'content_download_info': self.content_download_info.serialize()}

    def deserialize(self, data: dict):
        self.meta_list.deserialize(data['meta_list'])
        self.content_download_info.deserialize((data['content_download_info']))

    def __str__(self):
        return json.dumps(self.serialize())

    @staticmethod
    def example():
        return AlbumInfo(MetaList.example(), DownloadInfo())


class AlbumSpider:
    """
    在指定的目录下下载元数据和内容
    """

    def __init__(self, dir_path: str, meta_spider: MetaSpider, content_spider: ContentSpider):
        self.content_spider = content_spider
        self.dir_path = dir_path
        self.meta_spider = meta_spider
        pathlib.Path(dir_path).mkdir(parents=True, exist_ok=True)
        p = os.path.join(dir_path, meta_file_name)
        logging.info('正在载入: 相册 %s 下的相册元数据文件 %s' % (dir_path, p))
        album_info = AlbumInfo(MetaList([]), DownloadInfo('', '', None))
        if not os.path.exists(p):
            logging.warning('相册 %s 下的相册元数据文件 %s 不存在，写入 {}' % (dir_path, p))
            with open(p, "w") as f:
                json.dump(album_info.serialize(), f, indent=4)
        with open(p, "r") as f:
            album_info.deserialize(json.load(f))
        self.album_info = album_info
        logging.info('完成载入: 相册 %s 下的相册元数据文件 %s' % (dir_path, p))

    def save_meta(self):
        """
        将元数据下载信息保存到磁盘
        """
        p = os.path.join(self.dir_path, meta_file_name)
        logging.info('正在保存元数据到 %s' % p)
        with open(p, "w") as f:
            json.dump(self.album_info.serialize(), f, indent=4)
        logging.info('元数据已经保存到 %s' % p)

    def download_meta(self):
        """
        根据元数据中的下载信息更新元数据
        """
        logging.info('开始下载: %s 文件夹下的相册元数据' % self.dir_path)
        self.meta_spider.download_meta(self.album_info.meta_list)
        logging.info('完成下载: %s 文件夹下的相册元数据' % self.dir_path)

    def download_content(self):
        """
        根据元数据中的下载信息下载相册内容
        """
        logging.info('开始下载: %s 文件夹下的内容' % self.dir_path)
        self.content_spider.download_content(self.album_info.content_download_info, self.dir_path)
        logging.info('完成下载: %s 文件夹下的内容' % self.dir_path)
